package com.hup.sokoban.presenter;

import com.hup.sokoban.constant.MapConstant;
import com.hup.sokoban.model.common.MapItem;
import com.hup.sokoban.model.common.StepRecord;
import com.hup.sokoban.model.main.MainConfig;
import com.hup.sokoban.model.main.MapInfo;
import com.hup.sokoban.mvp.MainMvp.MainPresenter;
import com.hup.sokoban.service.main.StepRecordService;
import com.hup.sokoban.view.main.MainFrame;
import com.hup.sokoban.view.mapDesigner.MapDesignerFrame;
import com.hup.utils.commons.start.*;
import com.hup.utils.commons.start.SingletonAppManager.SingletonAppHandler;
import com.hup.utils.swing.frame.BaseWindow;
import com.hup.utils.swing.frame.SingletonWindowHelper;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import javax.swing.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hugan
 * @date 2020/4/28
 */
@Log4j2
@Component
public class MainPresenterImpl implements MainPresenter {

    @Getter
    private final MainConfig config;
    private SingletonAppManager singletonAppManager;

    public MainPresenterImpl() {
        config = new MainConfig().loadFromFile();
        log.info("config={}", config);
        SpringContext.getBean(SimpleExitHandler.class).setExitAction(this::exitAction);
    }

    private void exitAction() {
        singletonAppManager.doStop();
        System.exit(0);
    }

    @Override
    public void startUp() {
        MainFrame mainFrame = new MainFrame();

        singletonAppManager = SingletonAppManager.doStart(new SingletonAppHandler() {
            @Override
            public int port() {
                return config.appPort;
            }

            @Override
            public String appTag() {
                return StartupInfo.getApplicationName();
            }

            @Override
            public void onAppReduplicateStart() {
                SwingUtilities.invokeLater(() -> {
                    BaseWindow window = SingletonWindowHelper.getWindow(MapDesignerFrame.class);
                    if (window == null) {
                        window = SingletonWindowHelper.getWindow(MainFrame.class);
                    }

                    ((JFrame) window).setAlwaysOnTop(true);
                    ((JFrame) window).toFront();
                    ((JFrame) window).setAlwaysOnTop(false);
                });
            }

            @Override
            public String portSettingFileDesc() {
                return "config/MainConfig.config的appPort";
            }

            @Override
            public void onManagerThreadException(String desc, Exception e) {
                DialogHelper.show(desc, e, mainFrame);
            }
        });
        mainFrame.setVisible(true);
        //new MapDesignerFrame().setVisible(true);
    }

    @Override
    public ArrayList<MapItem> loadMapList() {
        File dir = new File(MapConstant.MAP_DIR);
        ArrayList<MapItem> res = new ArrayList<>();
        if (!dir.exists()) return res;

        //只加载已完成的地图
        File[] mapFiles = dir.listFiles((dir1, name) -> name.endsWith(MapConstant.EXT));
        if (mapFiles == null) return res;
        for (File mapFile : mapFiles) {
            MapItem item = MapItem.readFromFile(mapFile);
            res.add(item);
        }
        log.info("map数量={}", res.size());
        return res;
    }

    @Override
    public MapInfo getMapInfo(MapItem mapItem) {
        MapInfo res = new MapInfo();
        res.mapItem = mapItem;

        List<StepRecord> progress = StepRecordService.readFile(res, MapConstant.EXT_PROGRESS);
        boolean hadProgress = progress != null;
        if (hadProgress) res.lstProgressRecord = new ArrayList<>(progress);

        List<StepRecord> winning = StepRecordService.readFile(res, MapConstant.EXT_WINNING);
        boolean hadWinning = winning != null;
        if (hadWinning) res.lstWinningRecord = new ArrayList<>(winning);

        log.info("hadProgress={}, hadWinning={}", hadProgress, hadWinning);
        return res;
    }

    @Override
    public MapInfo getEmptyMapInfo() {
        MapInfo res = new MapInfo();
        res.mapItem = MapItem.getDefault();
        return res;
    }

    @Override
    public boolean isSame(MapItem curMap, MapItem original) {
        ArrayList<Integer> aliArea = curMap.getAliArea();
        for (Integer i : aliArea) {
            if (curMap.getMap()[i] != original.getMap()[i]) return false;
        }
        return true;
    }

    @Override
    public void saveProgress(MapInfo mapInfo) {
        StepRecordService.saveFile(mapInfo, MapConstant.EXT_PROGRESS);
    }

    @Override
    public void deleteProgress(MapInfo mapInfo) {
        StepRecordService.deleteFile(mapInfo, MapConstant.EXT_PROGRESS);
    }

    @Override
    public void saveWinning(MapInfo mapInfo) {
        StepRecordService.saveFile(mapInfo, MapConstant.EXT_WINNING);
    }

    @Override
    public void deleteWinning(MapInfo mapInfo) {
        StepRecordService.deleteFile(mapInfo, MapConstant.EXT_WINNING);
    }
}
